package global

import (
	"context"
	"fmt"
	"im/model/chat"
	"log"
	"os"
	"time"

	"github.com/go-redis/redis/v9"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

var (
	DB  *gorm.DB
	RD  *redis.Client
	Hub *chat.Hub
)

var CTX = context.Background()

// 初始化配置
func InitConfig() {
	viper.AddConfigPath("config")
	// 设置配置文件名称
	viper.SetConfigName("config")
	// 读取配置
	if err := viper.ReadInConfig(); err != nil {
		fmt.Printf(err.Error())
	}
	i := viper.Get("mysql")
	fmt.Printf("i: %v\n", i)

}

// 初始化数据库
func InitMysql() {

	// 自定义日志模板，打印sql语句
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),
		logger.Config{
			SlowThreshold: time.Second, // 慢 Sql阈值
			LogLevel:      logger.Info, // 日志级别
			Colorful:      true,        // 颜色
		},
	)

	d, err := gorm.Open(mysql.Open(viper.GetString("mysql.dns")),
		&gorm.Config{
			Logger: newLogger,
		})

	if err != nil {
		fmt.Printf("数据库连接失败")
		log.Fatal(err.Error())
	}

	DB = d
}

func InitRedis() {
	RD = redis.NewClient(&redis.Options{
		Addr: viper.GetString("redis.addr"),
		DB:   viper.GetInt("redis.db"),
		// Password:     viper.GetString("password"),
		PoolSize:     viper.GetInt("redis.poolSize"),
		MinIdleConns: viper.GetInt("redis.minIdleConns"),
		ReadTimeout:  viper.GetDuration("redis.readTimeout"),
	})

	if s, err := RD.Ping(CTX).Result(); err != nil {
		fmt.Printf(err.Error())
		fmt.Println("redis 连接失败....")
	} else {
		fmt.Println("连接成功：", s)
	}
}

const (
	PublishKey = "websocket"
)

// 发送消息到redis
func Publish(ctx context.Context, channel string, msg string) error {
	fmt.Printf("message: %v\n", msg)
	ic := RD.Publish(ctx, channel, msg)
	fmt.Printf("ic: %v\n", ic)
	err := RD.Publish(ctx, channel, msg).Err()
	return err
}

// 订阅消息
func Subscribe(ctx context.Context, channel string) (string, error) {
	sub := RD.Subscribe(ctx, channel)
	// defer sub.Close()
	fmt.Printf("cccc: %v\n", sub)

	/**
	c := sub.Channel()
	for msg := range c {
		fmt.Println(msg.Payload)
	}
	*/

	msg, err := sub.ReceiveMessage(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println(msg.Channel, msg.Payload)

	return msg.Payload, err

}
